/**
 * SSE客户端
 * 用于与Java服务端进行SSE通信
 */
class SseClient {
    constructor(baseUrl = 'http://localhost:8080') {
        this.baseUrl = baseUrl;
        this.eventSource = null;
        this.isConnected = false;
        this.sessionId = null;
        this.userId = null;
        this.token = null;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectDelay = 3000;
        this.messageHandlers = new Map();
        
        // 绑定方法到实例
        this.handleMessage = this.handleMessage.bind(this);
        this.handleError = this.handleError.bind(this);
        this.handleOpen = this.handleOpen.bind(this);
        this.handleClose = this.handleClose.bind(this);
    }

    /**
     * 连接到SSE服务
     * @param {string} token 用户认证token
     * @param {number} userId 用户ID
     * @returns {Promise} 连接结果
     */
    async connect(token, userId) {
        if (this.isConnected) {
            console.warn('SSE连接已存在，请先断开连接');
            return Promise.resolve();
        }

        this.token = token;
        this.userId = userId;

        return new Promise((resolve, reject) => {
            try {
                // 注意：EventSource不支持自定义headers，需要通过URL参数传递token
                const url = `${this.baseUrl}/api/client/sse/connect?token=${encodeURIComponent(token)}&userId=${userId}`;
                
                // 创建EventSource
                this.eventSource = new EventSource(url);

                // 设置事件监听器
                this.eventSource.onopen = (event) => {
                    this.handleOpen(event);
                    resolve();
                };

                this.eventSource.onerror = (event) => {
                    this.handleError(event);
                    reject(new Error('SSE连接失败'));
                };

                // 监听自定义事件
                this.eventSource.addEventListener('connected', this.handleMessage);
                this.eventSource.addEventListener('message', this.handleMessage);
                this.eventSource.addEventListener('notification', this.handleMessage);
                this.eventSource.addEventListener('error', this.handleMessage);
                this.eventSource.addEventListener('heartbeat', this.handleMessage);

                // 监听所有其他事件
                this.eventSource.onmessage = (event) => {
                    this.handleMessage(event);
                };

            } catch (error) {
                console.error('创建SSE连接失败:', error);
                reject(error);
            }
        });
    }

    /**
     * 使用sessionId连接到SSE服务
     * @param {string} token 用户认证token
     * @param {string} sessionId 会话ID
     * @returns {Promise} 连接结果
     */
    async connectWithSessionId(token, sessionId) {
        if (this.isConnected) {
            console.warn('SSE连接已存在，请先断开连接');
            return Promise.resolve();
        }

        this.token = token;
        this.sessionId = sessionId;

        return new Promise((resolve, reject) => {
            try {
                // 使用sessionId建立SSE连接
                const url = `${this.baseUrl}/api/client/sse/connect?token=${encodeURIComponent(token)}&sessionId=${encodeURIComponent(sessionId)}`;
                
                // 创建EventSource
                this.eventSource = new EventSource(url);

                // 设置事件监听器
                this.eventSource.onopen = (event) => {
                    this.handleOpen(event);
                    resolve();
                };

                this.eventSource.onerror = (event) => {
                    this.handleError(event);
                    reject(new Error('SSE连接失败'));
                };

                // 监听自定义事件
                this.eventSource.addEventListener('connected', this.handleMessage);
                this.eventSource.addEventListener('message', this.handleMessage);
                this.eventSource.addEventListener('notification', this.handleMessage);
                this.eventSource.addEventListener('error', this.handleMessage);
                this.eventSource.addEventListener('heartbeat', this.handleMessage);
                this.eventSource.addEventListener('stream', this.handleMessage);
                this.eventSource.addEventListener('complete', this.handleMessage);

                // 监听所有其他事件
                this.eventSource.onmessage = (event) => {
                    this.handleMessage(event);
                };

            } catch (error) {
                console.error('创建SSE连接失败:', error);
                reject(error);
            }
        });
    }

    /**
     * 断开SSE连接
     */
    disconnect() {
        if (this.eventSource) {
            this.eventSource.close();
            this.eventSource = null;
        }
        this.isConnected = false;
        this.sessionId = null;
        this.reconnectAttempts = 0;
        console.log('SSE连接已断开');
    }

    /**
     * 处理连接打开事件
     * @param {Event} event 
     */
    handleOpen(event) {
        this.isConnected = true;
        this.reconnectAttempts = 0;
        console.log('SSE连接已建立');
        
        // 触发连接成功事件
        this.triggerEvent('connected', { event });
    }

    /**
     * 处理连接关闭事件
     * @param {Event} event 
     */
    handleClose(event) {
        this.isConnected = false;
        console.log('SSE连接已关闭');
        
        // 触发连接关闭事件
        this.triggerEvent('disconnected', { event });
        
        // 尝试重连
        this.attemptReconnect();
    }

    /**
     * 处理错误事件
     * @param {Event} event 
     */
    handleError(event) {
        console.error('SSE连接错误:', event);
        
        if (this.eventSource) {
            this.eventSource.close();
        }
        
        this.isConnected = false;
        
        // 触发错误事件
        this.triggerEvent('error', { event });
        
        // 尝试重连
        this.attemptReconnect();
    }

    /**
     * 处理消息事件
     * @param {MessageEvent} event 
     */
    handleMessage(event) {
        try {
            let data = null;
            
            // 尝试解析JSON数据
            if (event.data) {
                try {
                    data = JSON.parse(event.data);
                } catch (e) {
                    data = event.data;
                }
            }

            const messageInfo = {
                event: event.type,
                data: data,
                timestamp: new Date().toISOString(),
                sessionId: this.sessionId,
                userId: this.userId
            };

            console.log('收到SSE消息:', messageInfo);

            // 处理连接成功事件
            if (event.type === 'connected' && data) {
                this.sessionId = data.sessionId;
                console.log('SSE会话ID:', this.sessionId);
            }

            // 触发消息事件
            this.triggerEvent('message', messageInfo);
            
            // 触发特定事件类型的处理器
            this.triggerEvent(event.type, messageInfo);

        } catch (error) {
            console.error('处理SSE消息失败:', error);
        }
    }

    /**
     * 尝试重连
     */
    attemptReconnect() {
        if (this.reconnectAttempts >= this.maxReconnectAttempts) {
            console.error('SSE重连次数已达上限，停止重连');
            this.triggerEvent('reconnect_failed', { attempts: this.reconnectAttempts });
            return;
        }

        this.reconnectAttempts++;
        console.log(`SSE重连尝试 ${this.reconnectAttempts}/${this.maxReconnectAttempts}`);

        setTimeout(() => {
            if (!this.isConnected && this.token && this.userId) {
                this.connect(this.token, this.userId)
                    .then(() => {
                        console.log('SSE重连成功');
                        this.triggerEvent('reconnected', { attempts: this.reconnectAttempts });
                    })
                    .catch((error) => {
                        console.error('SSE重连失败:', error);
                        this.attemptReconnect();
                    });
            }
        }, this.reconnectDelay * this.reconnectAttempts);
    }

    /**
     * 发送心跳
     * @returns {Promise} 心跳结果
     */
    async sendHeartbeat() {
        if (!this.sessionId) {
            throw new Error('会话ID不存在');
        }

        try {
            const response = await fetch(`${this.baseUrl}/api/client/sse/heartbeat/${this.sessionId}`, {
                method: 'GET',
                headers: {
                    'token': this.token
                }
            });

            if (response.ok) {
                const result = await response.json();
                console.log('心跳发送成功:', result);
                return result;
            } else {
                throw new Error(`心跳失败: ${response.status}`);
            }
        } catch (error) {
            console.error('发送心跳失败:', error);
            throw error;
        }
    }

    /**
     * 关闭连接
     * @returns {Promise} 关闭结果
     */
    async closeConnection() {
        if (!this.sessionId || !this.userId) {
            return Promise.resolve();
        }

        try {
            const response = await fetch(`${this.baseUrl}/api/client/sse/close/${this.userId}/${this.sessionId}`, {
                method: 'DELETE',
                headers: {
                    'token': this.token
                }
            });

            if (response.ok) {
                const result = await response.json();
                console.log('连接关闭成功:', result);
                this.disconnect();
                return result;
            } else {
                throw new Error(`关闭连接失败: ${response.status}`);
            }
        } catch (error) {
            console.error('关闭连接失败:', error);
            throw error;
        }
    }

    /**
     * 添加事件监听器
     * @param {string} eventType 事件类型
     * @param {Function} handler 处理函数
     */
    on(eventType, handler) {
        if (!this.messageHandlers.has(eventType)) {
            this.messageHandlers.set(eventType, []);
        }
        this.messageHandlers.get(eventType).push(handler);
    }

    /**
     * 移除事件监听器
     * @param {string} eventType 事件类型
     * @param {Function} handler 处理函数
     */
    off(eventType, handler) {
        const handlers = this.messageHandlers.get(eventType);
        if (handlers) {
            const index = handlers.indexOf(handler);
            if (index > -1) {
                handlers.splice(index, 1);
            }
        }
    }

    /**
     * 触发事件
     * @param {string} eventType 事件类型
     * @param {Object} data 事件数据
     */
    triggerEvent(eventType, data) {
        const handlers = this.messageHandlers.get(eventType);
        if (handlers) {
            handlers.forEach(handler => {
                try {
                    handler(data);
                } catch (error) {
                    console.error(`事件处理器错误 [${eventType}]:`, error);
                }
            });
        }
    }

    /**
     * 获取连接状态
     * @returns {Object} 连接状态信息
     */
    getStatus() {
        return {
            isConnected: this.isConnected,
            sessionId: this.sessionId,
            userId: this.userId,
            reconnectAttempts: this.reconnectAttempts,
            maxReconnectAttempts: this.maxReconnectAttempts
        };
    }

    /**
     * 设置重连参数
     * @param {number} maxAttempts 最大重连次数
     * @param {number} delay 重连延迟（毫秒）
     */
    setReconnectConfig(maxAttempts, delay) {
        this.maxReconnectAttempts = maxAttempts;
        this.reconnectDelay = delay;
    }
}

// 导出SSE客户端
if (typeof module !== 'undefined' && module.exports) {
    module.exports = SseClient;
} else if (typeof window !== 'undefined') {
    window.SseClient = SseClient;
} 